﻿#region itdc

/************************************************************************
*Copyright(C) 2015 by qsgy
 *All rights reserved. 
 *FileName:     $safeitemname$
 *Author:       oyh
 *Version:      
 *UnityVersion：
 *Date:   $time$      
 *Description:    
 *History: 
************************************************************************/
#endregion
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 状态id
/// </summary>
public enum StateID
{
    Null,Patrol,ChasePlayer,Attack,Empty
}


/// <summary>
/// 状态基类。
/// 继承mono。挂载使用。
/// </summary>
[RequireComponent(typeof(FSMSystem))]
public abstract class FSMState : MonoBehaviour {
    [Tooltip("唯一识别id，只读.在awake里初始化"), ReadOnly, SerializeField]
    protected StateID id = StateID.Null;
    [SerializeField, Tooltip("绑定的条件")]
    protected Transition[] transition;
    [SerializeField, Tooltip("对应条件的输出")]
    private StateID[] outPuts;
    protected FSMSystem system;//添加到的状态机系统
    private float freshTime = 0.3f;//刷新条件时间间隔
    #region prop

    public StateID Id
    {
        get
        {
            return id;
        }
    }
    public Transition[] Transition
    {
        get { return transition; }
    }

    public StateID[] OutPuts
    {
        get
        {
            return outPuts;
        }

        set
        {
            outPuts = value;
        }
    }


    #endregion

    /// <summary>
    /// 条件转换
    /// </summary>
    public virtual bool Reason()
    {
        if (transition.Length == 0) return false;
        for (int i = 0; i < transition.Length; i++)
        {
            if (transition[i].IsTransition())
            {
                transition[i].Exit();//条件退出
                system.ChangeState(OutPuts[i]);//交换状态
                return true;
            }
        }
        return false;
    }
    /// <summary>
    /// 状态进入时执行，启动reason刷新
    /// </summary>
    public virtual void DoBeforeEnter()
    {
        StartCoroutine(ReasonFresh());
        //print(id + "enter");
    }

    public virtual IEnumerator ReasonFresh()
    {
        yield return new WaitForSeconds(Random.Range(1f, 2f));//延迟一个随机数

        TransitionEnter();

        //print(Reason());
        while (!Reason())
        {
          //  print("fresh");
            CheckFresh();
            yield return new WaitForSeconds(freshTime);
        }
    }

    /// <summary>
    /// 开始使用状态时
    /// 初始化条件
    /// </summary>
    protected virtual void TransitionEnter()
    {
        foreach (var i in transition)
        {
            i.Enter();
        }
    }


    /// <summary>
    /// 状态刷新时调用
    /// </summary>
    public virtual void CheckFresh() { }

    private void OnDisable()
    {
        StopCoroutine("ReasonFresh");
    }

    /// <summary>
    /// 初实化system字段
    /// </summary>
    /// <param name="system"></param>
    public virtual void InitiSystem(FSMSystem system)
    {
        this.system = system;
        this.freshTime = system.freshTime;
#if DEBUG
        if (system == null) Debug.LogError(name + "can't find FSMSystem");
#endif
    }

    
}
